home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / DDATAOBJ / IENUMFE.CPP < prev    next >
C/C++ Source or Header  |  1993-04-14  |  5KB  |  264 lines

  1. /*
  2.  * IENUMFE.CPP
  3.  * Data Object for Chapter 6
  4.  *
  5.  * Full implementation of the IEnumFORMATETC interface that can be
  6.  * used generically for any FORMATETC enumerations given that the
  7.  * caller passes a count and pointer to array of FORMATETCs for this
  8.  * enumeration.
  9.  *
  10.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  11.  *
  12.  * Kraig Brockschmidt, Software Design Engineer
  13.  * Microsoft Systems Developer Relations
  14.  *
  15.  * Internet  :  kraigb@microsoft.com
  16.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  17.  */
  18.  
  19.  
  20. #include "dataobj.h"
  21.  
  22.  
  23. /*
  24.  * CEnumFormatEtc::CEnumFormatEtc
  25.  * CEnumFormatEtc::~CEnumFormatEtc
  26.  *
  27.  * Parameters (Constructor):
  28.  *  punkRef         LPUNKNOWN to use for reference counting.
  29.  *  cFE             ULONG number of FORMATETCs in pFE
  30.  *  prgFE           LPFORMATETC to the array over which to enumerate.
  31.  */
  32.  
  33. CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN punkRef, ULONG cFE
  34.     , LPFORMATETC prgFE)
  35.     {
  36.     UINT        i;
  37.  
  38.     m_cRef=0;
  39.     m_punkRef=punkRef;
  40.  
  41.     m_iCur=0;
  42.     m_cfe=cFE;
  43.  
  44.     m_prgfe=new FORMATETC[(UINT)cFE];
  45.  
  46.     if (NULL!=m_prgfe)
  47.         {
  48.         for (i=0; i < cFE; i++)
  49.             m_prgfe[i]=prgFE[i];
  50.         }
  51.  
  52.     return;
  53.     }
  54.  
  55.  
  56. CEnumFormatEtc::~CEnumFormatEtc(void)
  57.     {
  58.     if (NULL!=m_prgfe)
  59.         delete [] m_prgfe;
  60.  
  61.     return;
  62.     }
  63.  
  64.  
  65.  
  66.  
  67.  
  68. /*
  69.  * CEnumFormatEtc::QueryInterface
  70.  * CEnumFormatEtc::AddRef
  71.  * CEnumFormatEtc::Release
  72.  *
  73.  * Purpose:
  74.  *  IUnknown members for CEnumFormatEtc object.  For QueryInterface
  75.  *  we only return out own interfaces and not those of the data object.
  76.  *  However, since enumerating formats only makes sense when the data
  77.  *  object is around, we insure that it stays as long as we stay by
  78.  *  calling an outer IUnknown for ::AddRef and ::Release.  But since we
  79.  *  are not controlled by the lifetime of the outer object, we still keep
  80.  *  our own reference count in order to free ourselves.
  81.  */
  82.  
  83. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  84.     {
  85.     *ppv=NULL;
  86.  
  87.     /*
  88.      * Enumerators do not live on the same level as the data object, so
  89.      * we only need to support out IUnknown and IEnumFORMATETC interfaces
  90.      * here with no concern for aggregation.
  91.      */
  92.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
  93.         *ppv=(LPVOID)this;
  94.  
  95.     //AddRef any interface we'll return.
  96.     if (NULL!=*ppv)
  97.         {
  98.         ((LPUNKNOWN)*ppv)->AddRef();
  99.         return NOERROR;
  100.         }
  101.  
  102.     return ResultFromScode(E_NOINTERFACE);
  103.     }
  104.  
  105.  
  106. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  107.     {
  108.     ++m_cRef;
  109.     m_punkRef->AddRef();
  110.     return m_cRef;
  111.     }
  112.  
  113. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  114.     {
  115.     ULONG       cRefT;
  116.  
  117.     cRefT=--m_cRef;
  118.  
  119.     m_punkRef->Release();
  120.  
  121.     if (0==m_cRef)
  122.         delete this;
  123.  
  124.     return cRefT;
  125.     }
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. /*
  134.  * CEnumFormatEtc::Next
  135.  *
  136.  * Purpose:
  137.  *  Returns the next element in the enumeration.
  138.  *
  139.  * Parameters:
  140.  *  cFE             ULONG number of FORMATETCs to return.
  141.  *  pFE             LPFORMATETC in which to store the returned structures.
  142.  *  pulFE           ULONG FAR * in which to return how many we enumerated.
  143.  *
  144.  * Return Value:
  145.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  146.  */
  147.  
  148. STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE
  149.     , ULONG FAR * pulFE)
  150.     {
  151.     ULONG               cReturn=0L;
  152.  
  153.     if (NULL==m_prgfe)
  154.         return ResultFromScode(S_FALSE);
  155.  
  156.     if (NULL!=pulFE)
  157.         *pulFE=0L;
  158.  
  159.     if (NULL==pFE || m_iCur >= m_cfe)
  160.         return ResultFromScode(S_FALSE);
  161.  
  162.     while (m_iCur < m_cfe && cFE > 0)
  163.         {
  164.         *pFE++=m_prgfe[m_iCur++];
  165.         cReturn++;
  166.         cFE--;
  167.         }
  168.  
  169.     if (NULL!=pulFE)
  170.         *pulFE=(cReturn-cFE);
  171.  
  172.     return NOERROR;
  173.     }
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181. /*
  182.  * CEnumFormatEtc::Skip
  183.  *
  184.  * Purpose:
  185.  *  Skips the next n elements in the enumeration.
  186.  *
  187.  * Parameters:
  188.  *  cSkip           ULONG number of elements to skip.
  189.  *
  190.  * Return Value:
  191.  *  HRESULT         NOERROR if successful, S_FALSE if we could not
  192.  *                  skip the requested number.
  193.  */
  194.  
  195. STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
  196.     {
  197.     if ((m_iCur+cSkip) >= m_cfe)
  198.         return ResultFromScode(S_FALSE);
  199.  
  200.     m_iCur+=cSkip;
  201.     return NOERROR;
  202.     }
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. /*
  210.  * CEnumFormatEtc::Reset
  211.  *
  212.  * Purpose:
  213.  *  Resets the current element index in the enumeration to zero.
  214.  *
  215.  * Parameters:
  216.  *  None
  217.  *
  218.  * Return Value:
  219.  *  HRESULT         Always NOERROR
  220.  */
  221.  
  222. STDMETHODIMP CEnumFormatEtc::Reset(void)
  223.     {
  224.     m_iCur=0;
  225.     return NOERROR;
  226.     }
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233. /*
  234.  * CEnumFormatEtc::Clone
  235.  *
  236.  * Purpose:
  237.  *  Returns another IEnumFORMATETC with the same state as ourselves.
  238.  *
  239.  * Parameters:
  240.  *  ppEnum          LPENUMFORMATETC FAR * in which to return the new object.
  241.  *
  242.  * Return Value:
  243.  *  HRESULT         NOERROR if successful, error code otherwise.
  244.  */
  245.  
  246. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC FAR *ppEnum)
  247.     {
  248.     LPCEnumFormatEtc    pNew;
  249.  
  250.     *ppEnum=NULL;
  251.  
  252.     //Create the clone
  253.     pNew=new CEnumFormatEtc(m_punkRef, m_cfe, m_prgfe);
  254.  
  255.     if (NULL==pNew)
  256.         return ResultFromScode(E_OUTOFMEMORY);
  257.  
  258.     pNew->AddRef();
  259.     pNew->m_iCur=m_iCur;
  260.  
  261.     *ppEnum=pNew;
  262.     return NOERROR;
  263.     }
  264.